﻿using ILRuntime.Mono.Cecil;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using UnityEngine;
using UnityEngine.Experimental.AI;
using UnityEngine.Networking;

namespace Smart.Model.UI
{
    [ObjectSystem]
    public class TableComponentAwakeSystem : AwakeSystem<TableComponent>
    {
        public override void Awake(TableComponent self)
        {
            self.Awake();
        }
    }

    public class TableComponent : Component
    {
        protected Dictionary<string, System.Action<TableData>> mInitializeHandles = new Dictionary<string, Action<TableData>>(64);
        protected Dictionary<string, System.Func<TableHandle, object>> mCreatHandles = new Dictionary<string, Func<TableHandle, object>>(64);
        protected Dictionary<string, TableData> mTables = new Dictionary<string, TableData>(64);
        protected Dictionary<string, System.Action<object, TableHandle>> mBinds = new Dictionary<string, Action<object, TableHandle>>(64);
        protected const string mTableBundleName = "table";

        public void Awake()
        {
            Smart.Model.Logger.Log("<color=#00ff00>表格管理器启动成功</color>");
        }

        public Dictionary<string,TableData> GetLoadedTables()
        {
            return mTables;
        }

        public void Register(string table, System.Action<TableData> initialize,Func<TableHandle,object> handleFactory, Action<object,TableHandle> bind)
        {
            if (!mInitializeHandles.ContainsKey(table) && !this.Disposed)
            {
                mInitializeHandles.Add(table, initialize);
                mCreatHandles.Add(table, handleFactory);
                mBinds.Add(table, bind);
            }
        }

        public IEnumerator LoadTables(ResourceComponent ResourceComponent, System.Action onFailed)
        {
            if(this.Disposed)
            {
                Logger.LogError($"[表格加载]:TableComponent 组件已经被销毁");
                onFailed?.Invoke();
                yield break;
            }
            bool succeed = true;
            var loaders = Entry.Instance.EventSystem.GetTableLoaders();
            for (int i = 0,max = loaders.Count; succeed && i < max;++i)
            {
#if UNITY_EDITOR
                Stopwatch sw = new Stopwatch();
                sw.Start();
#endif
                var loader = loaders[i];
                var typeName = loader.FileName;
                ResourceComponent.LoadAsset<TextAsset>(mTableBundleName, typeName, textAsset =>
                {
                    var tableDatas = GDecoder.Load(textAsset.bytes,loader);
                    if (null != tableDatas)
                    {
                        mTables.Add(typeName, tableDatas);
                    }
                    else
                    {
                        succeed = false;
                    }
                },
                () =>
                {
                    succeed = false;
                });
#if UNITY_EDITOR
                sw.Stop();
                if (succeed)
                {
                    Logger.Log($"<color=#00ff00>[执行任务]:[表格加载] => [{typeName}] 耗时<color=#3dffff>[ {sw.ElapsedMilliseconds} ]</color>ms</color>");
                }
                else
                {
                    Logger.Log($"<color=#ff0000>[表格加载失败] => [{typeName}]</color>");
                    break;
                }
#endif
                yield return null;
            }

            for (var it = mInitializeHandles.GetEnumerator(); succeed && it.MoveNext();)
            {
#if UNITY_EDITOR
                Stopwatch sw = new Stopwatch();
                sw.Start();
#endif
                var typeName = it.Current.Key;
                ResourceComponent.LoadAsset<TextAsset>(mTableBundleName, typeName, textAsset =>
                {
                    var tableDatas = GDecoder.Load(textAsset.bytes, it.Current.Value, mCreatHandles[typeName], mBinds[typeName]);
                    if (null != tableDatas)
                    {
                        mTables.Add(typeName, tableDatas);
                    }
                    else
                    {
                        succeed = false;
                    }
                },
                () =>
                {
                    succeed = false;
                });

#if UNITY_EDITOR
                sw.Stop();
                if (succeed)
                {
                    Logger.Log($"<color=#00ff00>[执行任务]:[表格加载] => [{typeName}] 耗时<color=#3dffff>[ {sw.ElapsedMilliseconds} ]</color>ms</color>");
                }
                else
                {
                    Logger.Log($"<color=#ff0000>[表格加载失败] => [{typeName}]</color>");
                    break;
                }
#endif
                yield return null;
            }

            mInitializeHandles.Clear();
            mCreatHandles.Clear();
            mBinds.Clear();

            if (!succeed)
            {
                mTables.Clear();
                onFailed?.Invoke();
            }
        }

        public override void Dispose()
        {
            if (Disposed)
            {
                return;
            }

            mInitializeHandles?.Clear();
            mInitializeHandles = null;
            mCreatHandles?.Clear();
            mCreatHandles = null;
            mBinds?.Clear();
            mBinds = null;
            mTables?.Clear();
            mTables = null;

            base.Dispose();
        }
    }
}